library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;


entity Register_File is
generic (	N 		: positive := 32;		--number of bits in the registers
		N_ADDR 	: positive := 5);		--address size (determines number of registers)
port(	clock	 		: in   std_logic;
		reset			: in   std_logic;
		vliw_en			: in   std_logic;
		port_S_addr		: in   std_logic_vector (N_ADDR-1 downto 0);
		port_T_addr		: in   std_logic_vector (N_ADDR-1 downto 0);
		port_D_addr		: in   std_logic_vector (N_ADDR-1 downto 0);
		port_S_addr_vliw	: in   std_logic_vector (N_ADDR-1 downto 0);
		port_T_addr_vliw	: in   std_logic_vector (N_ADDR-1 downto 0);
		port_D_addr_vliw	: in   std_logic_vector (N_ADDR-1 downto 0);
		write_D_EN		: in   std_logic;
		write_D_EN_vliw	: in   std_logic;
		port_D_IN		: in   std_logic_vector (N-1 downto 0); 
		port_D_IN_vliw		: in   std_logic_vector (N-1 downto 0); 
		port_S_OUT		: out std_logic_vector (N-1 downto 0); 
		port_S_OUT_vliw	: out std_logic_vector (N-1 downto 0);  
		port_T_OUT		: out std_logic_vector (N-1 downto 0);  
		port_T_OUT_vliw	: out std_logic_vector (N-1 downto 0)   
);
end Register_File;

architecture Behavioral of Register_File is
constant N_REGS : positive := 2**N_ADDR;

subtype register_address is natural range 0 to N_REGS-1;
type register_array is array (register_address) of std_logic_vector(N-1 downto 0);

signal reg : register_array;

begin

	process (clock,reset,vliw_en)
	begin
		if reset = '1' then
			for i in 0 to N_REGS-1 loop
				for j in 0 to N-1 loop
					reg(i)(j) <= '0';
				end loop;  --j
			end loop;  -- i
		elsif rising_edge(clock) then
			if write_D_EN = '1' then
				reg(to_integer(unsigned(port_D_addr))) <= port_D_IN;
			end if;
			if write_D_EN_vliw = '1' and vliw_en = '1' then
				reg(to_integer(unsigned(port_D_addr_vliw))) <= port_D_IN_vliw;
			end if;
			
		end if;
	end process;
		
	port_S_OUT		<= reg(to_integer(unsigned(port_S_addr)));    --first register
	port_T_OUT		<= reg(to_integer(unsigned(port_T_addr)));    --second register
	port_S_OUT_vliw	<= reg(to_integer(unsigned(port_S_addr_vliw)));    --first register for vliw
	port_T_OUT_vliw	<= reg(to_integer(unsigned(port_T_addr_vliw)));    --second register for vliw
			
end Behavioral;
